﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using Sustainalytics.Governance.Reporting;
using Sustainalytics.Utils;
using Sustainalytics.Entities.ConnectionStrings;
using Sustainalytics.DataLayer.ConnectionStrings;
using System.Configuration;
using Sustainalytics.Entities;
using MongoDB.Driver;
using Sustainalytics.AwsS3.Client;
using Sustainalytics.MongoDB.Extensions;
using Sustainalytics.Utils.Configuration;
using System.Web.Http.Cors;

namespace Sustainalytics.Governance.Service.Controllers
{
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    [RoutePrefix("api/v1")]
    [LogControllerFilter(true, true, false)]
    public class CompanyReportController : ApiController
    {
        private readonly string _clientPlatformConnectionString;
        private readonly string _inputFilesConnectionString;
        private IReportsManager _reportsManager;

        public CompanyReportController()
        {
            _clientPlatformConnectionString = ConfigurationManager.ConnectionStrings["ClientPlatform"].ConnectionString;
            _inputFilesConnectionString = ConfigurationManager.ConnectionStrings["GovernanceInputFile"].ConnectionString;
        }

        public CompanyReportController(IReportsManager reportsManager)
        {
            _reportsManager = reportsManager;
        }

        private string GetConnectionString(ConnectionStringType connectionStringType)
        {
            var connectionStringsManager =
                ConnectionStringsManager.GetInstance(
                    ConnectionStringsRepository.GetInstance(_clientPlatformConnectionString));

            return connectionStringsManager.GetConnectionString(connectionStringType);
        }

        private IReportsManager GetReportManager(string databaseGroup)
        {
            var dwConnectionString = GetConnectionString(ConnectionStringType.GovernanceDW);

            if (dwConnectionString.Contains("GovernanceDW_A"))
                dwConnectionString = dwConnectionString.Replace("GovernanceDW_A", $"GovernanceDW_{databaseGroup}");
            if (dwConnectionString.Contains("GovernanceDW_B"))
                dwConnectionString = dwConnectionString.Replace("GovernanceDW_B", $"GovernanceDW_{databaseGroup}");


            var connectionStrings = new Dictionary<string, string>
            {
                {"GovernanceDW", dwConnectionString},
                {"GovernanceInputFile", _inputFilesConnectionString}
            };


            var reportsManager = ReportsManager.GetInstance(100, connectionStrings, databaseGroup);


            return reportsManager;
        }

        [Route("progress")]
        public HttpResponseMessage Get()
        {
            HttpResponseMessage response;
            try
            {
                var result = _reportsManager.Progress;

                response = Request.CreateResponse(HttpStatusCode.OK, result);
            }
            catch (Exception ex)
            {
                GovernanceEventSource.Log.LogError(ex);
                response = Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);
            }
            return response;
        }



        [Route("company/{companyId}/companyReport")]
        public HttpResponseMessage Get(Guid companyId)
        {
            try
            {
                var result = TryGetReportFromS3(companyId);
                return Request.CreateResponse(HttpStatusCode.OK, result);
            }
            catch (Exception ex)
            {
                CommonEventSource.Log.Exception(ex);
                return Request.CreateResponse(HttpStatusCode.InternalServerError,
                    string.Format("Failed to generate the Company Report with company ID={0} Error:{1}", companyId, ex));
            }
        }

        private GovernancePdfReport TryGetReportFromS3(Guid companyId)
        {
            var s3BucketName = SettingsHelper.Read("s3bucket", "dev-globalaccess-europe");

            var s3Client = new S3Client(
                new S3ClientSettings
                {
                    AccessKey = SettingsHelper.Read("accesKeyId", "AKIAJEMY5FHDRQOHGPVA"),
                    SecretAccessKey = SettingsHelper.Read("awsSecretKey", "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"),
                    ServiceEndPoint = SettingsHelper.Read("s3ServiceEndPoint", "https://s3-eu-west-1.amazonaws.com/")
                });


            var dwConnectionString = GetConnectionString(ConnectionStringType.GovernanceDW);


            string databaseGroup = null;

            if (dwConnectionString.Contains("GovernanceDW_A"))
                databaseGroup = "A";
            if (dwConnectionString.Contains("GovernanceDW_B"))
                databaseGroup = "B";

            if (string.IsNullOrWhiteSpace(databaseGroup))
                throw new ArgumentNullException("databaseGroup");

            var filePath = $"{ReportType.CorporateGovernanceCompanyReport}_{databaseGroup}";

            var companyProfile = MongoFactory.GetCollectionFromDatabase<GovernanceCompanyProfile>(dwConnectionString)
                .Find(x => x.Id == companyId)
                .Project<GovernanceCompanyProfile>(Builders<GovernanceCompanyProfile>.Projection
                    .Include(x=> x.CompanyName))
                .FirstOrDefault();

            if (companyProfile == null) return null;

            var fileName = ReportName.CG.GetFullReportName(companyProfile.CompanyName, companyId);
            var remotePath = $"{filePath}/{fileName}";

            if (!s3Client.FileExists(s3BucketName, remotePath))
            {
                _reportsManager = GetReportManager(databaseGroup);

                var successfully = _reportsManager.GeneratePdfReport(companyId);

                if (!successfully)
                    return null;
            }

            var file = new GovernancePdfReport
            {
                Id = companyId,
                FileName = ReportName.CG.GetFullReportName(companyProfile.CompanyName, DateTime.UtcNow),
                S3Bucket = s3BucketName,
                S3Key = remotePath
            };

            return file;
        }

    }
}
